]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Disconnect from window user time notifications, only sort when mapped
authorColin Walters <walters@verbum.org>
Fri, 2 Oct 2009 19:55:55 +0000 (15:55 -0400)
committerColin Walters <walters@verbum.org>
Tue, 6 Oct 2009 16:49:43 +0000 (12:49 -0400)
Before we were badly leaking AppIcons by not disconnecting from the
window signal handlers when our actor got destroyed.  This caused
us to repeatedly re-sort the windows for each AppIcon that
had ever been displayed with obvious bad consequences.

Besides simply chaining the signals to the lifetime of the AppIcon
actor, we also only do the sorting if we're mapped.  This decreases
the amount of work to do in the not-mapped case.

https://bugzilla.gnome.org/show_bug.cgi?id=597120

js/ui/appIcon.js

index 5585eb0601dfc8e34f9503d687e819c3c97f3654..d7dbd7726110070f67ca6e4738312162b400a130 100644 (file)
@@ -70,13 +70,21 @@ AppIcon.prototype = {
                                            reactive: true });
         this.actor._delegate = this;
         this.highlight_border_color = APPICON_DEFAULT_BORDER_COLOR;
+        this._signalIds = [];
 
+        // Note, we don't presently update the window list dynamically here; this actor
+        // gets destroyed and recreated by AppWell, and in alt-tab the whole thing is
+        // created each time
         this.windows = Shell.AppMonitor.get_default().get_windows_for_app(this.appInfo.get_id());
         for (let i = 0; i < this.windows.length; i++) {
-            this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows));
+            let sigId = this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows));
+            this._signalIds.push([this.windows[i], sigId]);
         }
         this._resortWindows();
 
+        this.actor.connect('destroy', Lang.bind(this, this._destroy));
+        this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedChanged));
+
         if (this._menuType != MenuType.NONE) {
             this.actor.connect('button-press-event', Lang.bind(this, this._updateMenuOnButtonPress));
             this.actor.connect('notify::hover', Lang.bind(this, this._updateMenuOnHoverChanged));
@@ -167,7 +175,26 @@ AppIcon.prototype = {
         }
     },
 
+    _destroy: function() {
+        for (let i = 0; i < this._signalIds.length; i++) {
+            let [obj, sigId] = this._signalIds[i];
+            obj.disconnect(sigId);
+        }
+    },
+
+    _onMappedChanged: function() {
+        let mapped = this.actor.mapped;
+        if (mapped && this._windowSortStale)
+            this._resortWindows();
+    },
+
     _resortWindows: function() {
+        let mapped = this.actor.mapped;
+        if (!mapped) {
+            this._windowSortStale = true;
+            return;
+        }
+        this._windowSortStale = false;
         this.windows.sort(function (a, b) {
             let activeWorkspace = global.screen.get_active_workspace();
             let wsA = a.get_workspace() == activeWorkspace;